package com.intelligent.bot.base.exception;

import com.intelligent.bot.base.result.B;
import com.intelligent.bot.model.ErrorMessage;
import com.intelligent.bot.service.IErrorMessageService;
import com.intelligent.bot.utils.sys.JwtUtil;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;

@ControllerAdvice
@Log4j2
public class ExceptionHandle {

    @Resource
    IErrorMessageService errorMessageService;

    /**
     * 异常处理
     * @param e 异常信息
     * @return 返回类是我自定义的接口返回类，参数是返回码和返回结果，异常的返回结果为空字符串
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public B<Void> handle(Exception e) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        ErrorMessage errorMessage = getErrorMessage(e, request);
        errorMessageService.save(errorMessage);
        //自定义异常返回对应编码
        if (e instanceof E ex) {
            return B.finalBuild(ex.getMessage());
        }
        //其他异常报对应的信息
        else {
            log.error("[系统异常]{}", e.getMessage());
            return B.finalBuild("哎呦！系统开小差了，等会再试试呢");
        }

    }

    private static ErrorMessage getErrorMessage(Exception e, HttpServletRequest request) {
        ErrorMessage errorMessage = new ErrorMessage();
        errorMessage.setErrorMessage(e.getMessage());
        errorMessage.setUrl(request.getServletPath());
        StackTraceElement[] stackTrace = e.getStackTrace();
        if (stackTrace.length > 0) {
            // 获取抛出异常位置的堆栈跟踪元素
            StackTraceElement element = stackTrace[0];
            // 获取报错的文件名
            String fileName = element.getFileName();
            // 获取报错的行号
            int lineNumber = element.getLineNumber();
            errorMessage.setPosition("file:"+fileName+"\nlineNumber:"+lineNumber);
        }
        errorMessage.setErrorMessage(null == errorMessage.getErrorMessage() ? e.getStackTrace()[0].toString() : errorMessage.getErrorMessage());
        errorMessage.setUserId(JwtUtil.getUserId());
        return errorMessage;
    }
}
